Overall Objective

Load Libraries

library(tidyverse)
library(cowplot)
library(broom)

Import data

Convert data from ‘wide’ to ‘long’ format

Factor the data into categorical variables

# Refactoring Columns for samples
data2$Sample_ID <- as.factor(data2$Sample_ID)
data2$Dilution_factor <- as.numeric(data2$Dilution_factor)
data2$Injection<- as.factor(data2$Injection)
data2$Tech_rep <- as.numeric(data2$Tech_rep)
data2
# Refactoring COlumns for key
key$Sample_ID <- as.factor(key$Sample_ID)
key$Animal <- as.factor(key$Animal)
key$Condition <- as.factor(key$Condition)
key
# Refactoring columns for standards
standards2$Sample_ID <- as.factor(standards2$Sample_ID)
standards2$When <- as.factor(standards2$When)
standards2$Dilution_factor <- as.numeric(standards2$Dilution_factor)
standards2$Injection <- as.factor(standards2$Injection)
standards2$Nano_day <- as.numeric(standards2$Nano_day)
standards2

Back calculate standards

standards2 <- standards2 %>% 
  mutate(True_Count=Dilution_factor*Count)
# Set the correct order of 'categorical factors'
standards2$Nano_day <-  factor(standards2$Nano_day, levels=c('1'))
standards2$When <- factor(standards2$When, levels=c('before','after'))
standards2

Summarize three technical standard replicates

standards3 <- standards2 %>% 
  group_by(particle_size,Sample_ID,When,Dilution_factor,Nano_day,Injection) %>% 
  summarise( tech_N = length(True_Count),
             tech_mean = mean(True_Count),
             tech_sd = sd(True_Count),
             tech_se = tech_sd/sqrt(tech_N))
standards3

Summarize standards by injection

standards4 <- standards3 %>% 
  group_by(Nano_day,When,particle_size) %>% 
  summarise( inj_N = length(tech_mean),
             inj_mean = mean(tech_mean),
             inj_sd = sd(tech_mean),
             inj_se = inj_sd/sqrt(inj_N))
standards4

Plot before and after plots, facet by experimental day

std_plot <- standards4 %>% 
  ggplot(aes(x=particle_size,y=inj_mean,color=When))+
  geom_ribbon(aes(ymin=inj_mean-inj_se, ymax=inj_mean+inj_se),alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=2) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Condition")+ #Label table title
  facet_grid(. ~ When)
std_plot

Standards particle concentrations from each experimental day

standards_df <- standards4 %>% 
  group_by(Nano_day,When) %>% 
  summarise(total=sum(inj_mean))
standards_df

Bar graph of standards particle concentrations

standards_df %>% 
  ggplot(aes(x=Nano_day,y=total,fill=When))+
  geom_col(position="dodge")+
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Experimental Day") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="When") #Label table title

Intraassay variability

Intra.assay_cv <- standards_df %>% 
  group_by(Nano_day) %>% 
  summarise(Day_N = length(total),
             Day_mean = mean(total),
             Day_sd = sd(total),
             Day_se = Day_sd/sqrt(Day_N),
            Day_cv = Day_sd/Day_mean )
Intra.assay_cv

Sample analysis

Back calculate the original concentration of the sample

data2 <- data2 %>% 
  mutate(True_Count = Dilution_factor*Count)
data2

Average three technical readings

data3 <- data2 %>% 
  group_by(particle_size,Sample_ID,Dilution_factor,Injection) %>% 
  summarise( tech_N = length(True_Count),
             tech_mean = mean(True_Count),
             tech_sd = sd(True_Count),
             tech_se = tech_sd/sqrt(tech_N))
data3

Summarize samples by injection (average both injections)

data4 <- data3 %>% 
  group_by(particle_size,Sample_ID,Dilution_factor) %>% 
  summarise( inj_N = length(tech_mean),
             inj_mean = mean(tech_mean),
             inj_sd = sd(tech_mean),
             inj_se = inj_sd/sqrt(inj_N))
data4
# Average technical replicates and merge with key
merge <- left_join(key,data3, by= "Sample_ID")
merge
# Average injection replicates and merge with key
merge1 <- left_join(key,data4, by= "Sample_ID")
merge1

Quick visualizations

Graphing all samples

sample_plot <- merge %>%
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se,
                  ymax=tech_mean+tech_se),
                  alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=2.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_grid(Animal ~ Condition)+
  geom_vline(xintercept = 140)+
  annotate("text", x= 235, y = 1E9, label= "140nm")
sample_plot

Particle concentration values for each of the samples

merge2 <- merge1 %>% 
  group_by(Animal,Condition) %>% 
  summarise(particle_conc=sum(inj_mean))
merge2

Summary statistics of particle concentration (averaging n=6 for each time point)

merge3 <- merge2 %>% 
  group_by(Condition) %>% 
  summarise(Condition_N=length(particle_conc),
            Condition_mean = mean(particle_conc),
            Condition_sd = sd(particle_conc),
            Condition_se = Condition_sd/sqrt(Condition_N))
merge3

Boxplot

plot1 <- merge2 %>% 
  #filter(!Animal== '1371'|!Condition == 'lowOxygen') %>% 
  group_by(Condition) %>% 
  ggplot(aes(x= Condition, y = particle_conc, color=Condition)) +
  geom_boxplot(colour="black",fill=NA) + 
  geom_point(aes(text = paste("Animal:", Animal)),
             position='jitter',size=3)+
  xlab("\nTreatment\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("GD 17.5 Placental Exosome \nExplant Culture (Ultracentrigution)\n")+ #title
  labs(color="Condition") # Label table title
  
plot1

Interactive Plot

ggplotly(plot1)

Statistics

fit <- t.test(particle_conc ~ Condition,data=merge2)
tidy(fit)
LS0tDQp0aXRsZTogIkV4cGxhbnQgQ3VsdHVyZSBBbmFseXNpcyINCmF1dGhvcjogIlNlYW4gTmd1eWVuIg0Kb3V0cHV0Og0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCiNPdmVyYWxsIE9iamVjdGl2ZSANCg0KDQojI0xvYWQgTGlicmFyaWVzDQoNCmBgYHtyLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoY293cGxvdCkNCmxpYnJhcnkoYnJvb20pDQpsaWJyYXJ5KHBsb3RseSkNCmBgYA0KDQojI0ltcG9ydCBkYXRhDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCnNldHdkKCJ+L0dpdEh1Yi9FeHBlcmltZW50cy9leHBsYW50X2NvbmRpdGlvbnMiKQ0KI3NldHdkKCJ+L0xpYnJhcnkvTW9iaWxlXCBEb2N1bWVudHMvY29tfmFwcGxlfkNsb3VkRG9jcy90aW1lLWNvdXJzZS9kYXRhIikNCg0KcmF3X2RhdGEgPC0gImV4cGxhbnRfY29tYmluZWQtRXhwZXJpbWVudFN1bW1hcnkuY3N2Ig0Ka2V5X2RhdGEgPC0gImV4cGxhbnRfa2V5LmNzdiINCnN0YW5kYXJkX2RhdGEgPC0gInN0YW5kYXJkc19jb21iaW5lZC1FeHBlcmltZW50U3VtbWFyeS5jc3YiDQoNCg0KZGF0YSA8LSByZWFkX2NzdihyYXdfZGF0YSkNCnN0YW5kYXJkcyA8LSByZWFkX2NzdihzdGFuZGFyZF9kYXRhKQ0Ka2V5IDwtIHJlYWRfY3N2KGtleV9kYXRhKQ0KDQpkYXRhDQpzdGFuZGFyZHMNCmtleQ0KYGBgDQoNCiMjQ29udmVydCBkYXRhIGZyb20gJ3dpZGUnIHRvICdsb25nJyBmb3JtYXQNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBkYXRhDQpkYXRhMSA8LSBkYXRhICU+JQ0KICBnYXRoZXIoU2FtcGxlLENvdW50LDI6MzcpDQoNCiMgU2VwYXJhdGUgc2FtcGxlcyBieSBpZGVudGlmaWVycyANCmRhdGEyIDwtIGRhdGExICU+JSANCiAgc2VwYXJhdGUoU2FtcGxlLCBpbnRvPWMoIlNhbXBsZV9JRCIsIkRpbHV0aW9uX2ZhY3RvciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICJJbmplY3Rpb24iLCJUZWNoX3JlcCIsIHNlcCA9ICJfIikpICU+JSANCiAgc2VsZWN0KC1gX2ApDQoNCiMgU3RhbmRhcmRzDQpzdGFuZGFyZHMxIDwtIHN0YW5kYXJkcyAlPiUgDQogIGdhdGhlcihTYW1wbGUsQ291bnQsMjoxMykNCg0KDQpzdGFuZGFyZHMyIDwtIHN0YW5kYXJkczEgJT4lIA0KICBzZXBhcmF0ZShTYW1wbGUsIGludG89YygiU2FtcGxlX0lEIiwiV2hlbiIsIkRpbHV0aW9uX2ZhY3RvciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICJOYW5vX2RheSIsIkluamVjdGlvbiIsIlRlY2hfUmVwIiwgc2VwID0gIl8iKSkgJT4lIA0KICBzZWxlY3QoLWBfYCkNCg0KDQpgYGANCg0KDQojI0ZhY3RvciB0aGUgZGF0YSBpbnRvIGNhdGVnb3JpY2FsIHZhcmlhYmxlcw0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQojIFJlZmFjdG9yaW5nIENvbHVtbnMgZm9yIHNhbXBsZXMNCmRhdGEyJFNhbXBsZV9JRCA8LSBhcy5mYWN0b3IoZGF0YTIkU2FtcGxlX0lEKQ0KZGF0YTIkRGlsdXRpb25fZmFjdG9yIDwtIGFzLm51bWVyaWMoZGF0YTIkRGlsdXRpb25fZmFjdG9yKQ0KZGF0YTIkSW5qZWN0aW9uPC0gYXMuZmFjdG9yKGRhdGEyJEluamVjdGlvbikNCmRhdGEyJFRlY2hfcmVwIDwtIGFzLm51bWVyaWMoZGF0YTIkVGVjaF9yZXApDQoNCmRhdGEyDQoNCiMgUmVmYWN0b3JpbmcgQ09sdW1ucyBmb3Iga2V5DQprZXkkU2FtcGxlX0lEIDwtIGFzLmZhY3RvcihrZXkkU2FtcGxlX0lEKQ0Ka2V5JEFuaW1hbCA8LSBhcy5mYWN0b3Ioa2V5JEFuaW1hbCkNCmtleSRDb25kaXRpb24gPC0gYXMuZmFjdG9yKGtleSRDb25kaXRpb24pDQoNCmtleQ0KDQojIFJlZmFjdG9yaW5nIGNvbHVtbnMgZm9yIHN0YW5kYXJkcw0Kc3RhbmRhcmRzMiRTYW1wbGVfSUQgPC0gYXMuZmFjdG9yKHN0YW5kYXJkczIkU2FtcGxlX0lEKQ0Kc3RhbmRhcmRzMiRXaGVuIDwtIGFzLmZhY3RvcihzdGFuZGFyZHMyJFdoZW4pDQpzdGFuZGFyZHMyJERpbHV0aW9uX2ZhY3RvciA8LSBhcy5udW1lcmljKHN0YW5kYXJkczIkRGlsdXRpb25fZmFjdG9yKQ0Kc3RhbmRhcmRzMiRJbmplY3Rpb24gPC0gYXMuZmFjdG9yKHN0YW5kYXJkczIkSW5qZWN0aW9uKQ0Kc3RhbmRhcmRzMiROYW5vX2RheSA8LSBhcy5udW1lcmljKHN0YW5kYXJkczIkTmFub19kYXkpDQoNCnN0YW5kYXJkczINCg0KYGBgDQoNCg0KDQojIyNCYWNrIGNhbGN1bGF0ZSBzdGFuZGFyZHMNCmBgYHtyfQ0Kc3RhbmRhcmRzMiA8LSBzdGFuZGFyZHMyICU+JSANCiAgbXV0YXRlKFRydWVfQ291bnQ9RGlsdXRpb25fZmFjdG9yKkNvdW50KQ0KDQojIFNldCB0aGUgY29ycmVjdCBvcmRlciBvZiAnY2F0ZWdvcmljYWwgZmFjdG9ycycNCnN0YW5kYXJkczIkTmFub19kYXkgPC0gIGZhY3RvcihzdGFuZGFyZHMyJE5hbm9fZGF5LCBsZXZlbHM9YygnMScpKQ0Kc3RhbmRhcmRzMiRXaGVuIDwtIGZhY3RvcihzdGFuZGFyZHMyJFdoZW4sIGxldmVscz1jKCdiZWZvcmUnLCdhZnRlcicpKQ0KDQpzdGFuZGFyZHMyDQpgYGANCg0KIyMjU3VtbWFyaXplIHRocmVlIHRlY2huaWNhbCBzdGFuZGFyZCByZXBsaWNhdGVzDQpgYGB7cn0NCnN0YW5kYXJkczMgPC0gc3RhbmRhcmRzMiAlPiUgDQogIGdyb3VwX2J5KHBhcnRpY2xlX3NpemUsU2FtcGxlX0lELFdoZW4sRGlsdXRpb25fZmFjdG9yLE5hbm9fZGF5LEluamVjdGlvbikgJT4lIA0KICBzdW1tYXJpc2UoIHRlY2hfTiA9IGxlbmd0aChUcnVlX0NvdW50KSwNCiAgICAgICAgICAgICB0ZWNoX21lYW4gPSBtZWFuKFRydWVfQ291bnQpLA0KICAgICAgICAgICAgIHRlY2hfc2QgPSBzZChUcnVlX0NvdW50KSwNCiAgICAgICAgICAgICB0ZWNoX3NlID0gdGVjaF9zZC9zcXJ0KHRlY2hfTikpDQpzdGFuZGFyZHMzDQpgYGANCg0KDQojIyNTdW1tYXJpemUgc3RhbmRhcmRzIGJ5IGluamVjdGlvbg0KYGBge3J9DQpzdGFuZGFyZHM0IDwtIHN0YW5kYXJkczMgJT4lIA0KICBncm91cF9ieShOYW5vX2RheSxXaGVuLHBhcnRpY2xlX3NpemUpICU+JSANCiAgc3VtbWFyaXNlKCBpbmpfTiA9IGxlbmd0aCh0ZWNoX21lYW4pLA0KICAgICAgICAgICAgIGlual9tZWFuID0gbWVhbih0ZWNoX21lYW4pLA0KICAgICAgICAgICAgIGlual9zZCA9IHNkKHRlY2hfbWVhbiksDQogICAgICAgICAgICAgaW5qX3NlID0gaW5qX3NkL3NxcnQoaW5qX04pKQ0Kc3RhbmRhcmRzNA0KDQpgYGANCg0KIyMjUGxvdCBiZWZvcmUgYW5kIGFmdGVyIHBsb3RzLCBmYWNldCBieSBleHBlcmltZW50YWwgZGF5DQpgYGB7cn0NCnN0ZF9wbG90IDwtIHN0YW5kYXJkczQgJT4lIA0KICBnZ3Bsb3QoYWVzKHg9cGFydGljbGVfc2l6ZSx5PWlual9tZWFuLGNvbG9yPVdoZW4pKSsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW49aW5qX21lYW4taW5qX3NlLCB5bWF4PWlual9tZWFuK2lual9zZSksDQogICAgICAgICAgICAgIGFscGhhPTAuMixmaWxsID0gYWxwaGEoJ2dyZXkxMicsIDAuMikpICsgI2Vycm9yIGJhcnMNCiAgZ2VvbV9saW5lKHNpemU9MikgKyB4bGltKDAsNTAwKSsgI2xpbmUgc2l6ZSwgeC1heGlzIHNjYWxlDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQ9YygwLDApKSsgI3NldCBib3R0b20gb2YgZ3JhcGgNCiAgeGxhYigiUGFydGljbGUgU2l6ZSIpICsgIyBYIGF4aXMgbGFiZWwNCiAgeWxhYigiXG5NZWFuIFBhcnRpY2xlIENvbmNlbnRyYXRpb24vbWxcbiIpICsgIyBZIGF4aXMgbGFiZWwNCiAgZ2d0aXRsZSgiTmFub3NpZ2h0IEhpc3RvZ3JhbSBvZlxuVmlyZ2luIE1vdXNlIFBsYXNtYSIpKyAjdGl0bGUNCiAgbGFicyhjb2xvcj0iQ29uZGl0aW9uIikrICNMYWJlbCB0YWJsZSB0aXRsZQ0KICBmYWNldF9ncmlkKC4gfiBXaGVuKQ0KDQpzdGRfcGxvdA0KDQpgYGANCg0KIyMjIFN0YW5kYXJkcyBwYXJ0aWNsZSBjb25jZW50cmF0aW9ucyBmcm9tIGVhY2ggZXhwZXJpbWVudGFsIGRheQ0KYGBge3J9DQpzdGFuZGFyZHNfZGYgPC0gc3RhbmRhcmRzNCAlPiUgDQogIGdyb3VwX2J5KE5hbm9fZGF5LFdoZW4pICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsPXN1bShpbmpfbWVhbikpDQoNCnN0YW5kYXJkc19kZg0KYGBgDQoNCiMjI0JhciBncmFwaCBvZiBzdGFuZGFyZHMgcGFydGljbGUgY29uY2VudHJhdGlvbnMNCmBgYHtyfQ0Kc3RhbmRhcmRzX2RmICU+JSANCiAgZ2dwbG90KGFlcyh4PU5hbm9fZGF5LHk9dG90YWwsZmlsbD1XaGVuKSkrDQogIGdlb21fY29sKHBvc2l0aW9uPSJkb2RnZSIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kPWMoMCwwKSkrICNzZXQgYm90dG9tIG9mIGdyYXBoDQogIHhsYWIoIkV4cGVyaW1lbnRhbCBEYXkiKSArICMgWCBheGlzIGxhYmVsDQogIHlsYWIoIlxuTWVhbiBQYXJ0aWNsZSBDb25jZW50cmF0aW9uL21sXG4iKSArICMgWSBheGlzIGxhYmVsDQogIGdndGl0bGUoIk5hbm9zaWdodCBIaXN0b2dyYW0gb2ZcblZpcmdpbiBNb3VzZSBQbGFzbWEiKSsgI3RpdGxlDQogIGxhYnMoY29sb3I9IldoZW4iKSAjTGFiZWwgdGFibGUgdGl0bGUNCmBgYA0KDQojIyNJbnRyYWFzc2F5IHZhcmlhYmlsaXR5DQpgYGB7cn0NCkludHJhLmFzc2F5X2N2IDwtIHN0YW5kYXJkc19kZiAlPiUgDQogIGdyb3VwX2J5KE5hbm9fZGF5KSAlPiUgDQogIHN1bW1hcmlzZShEYXlfTiA9IGxlbmd0aCh0b3RhbCksDQogICAgICAgICAgICAgRGF5X21lYW4gPSBtZWFuKHRvdGFsKSwNCiAgICAgICAgICAgICBEYXlfc2QgPSBzZCh0b3RhbCksDQogICAgICAgICAgICAgRGF5X3NlID0gRGF5X3NkL3NxcnQoRGF5X04pLA0KICAgICAgICAgICAgRGF5X2N2ID0gRGF5X3NkL0RheV9tZWFuICkNCkludHJhLmFzc2F5X2N2DQpgYGANCg0KI1NhbXBsZSBhbmFseXNpcw0KDQojIyNCYWNrIGNhbGN1bGF0ZSB0aGUgb3JpZ2luYWwgY29uY2VudHJhdGlvbiBvZiB0aGUgc2FtcGxlDQpgYGB7cn0NCmRhdGEyIDwtIGRhdGEyICU+JSANCiAgbXV0YXRlKFRydWVfQ291bnQgPSBEaWx1dGlvbl9mYWN0b3IqQ291bnQpDQpkYXRhMg0KYGBgDQoNCg0KIyMjIEF2ZXJhZ2UgdGhyZWUgdGVjaG5pY2FsIHJlYWRpbmdzDQpgYGB7cn0NCmRhdGEzIDwtIGRhdGEyICU+JSANCiAgZ3JvdXBfYnkocGFydGljbGVfc2l6ZSxTYW1wbGVfSUQsRGlsdXRpb25fZmFjdG9yLEluamVjdGlvbikgJT4lIA0KICBzdW1tYXJpc2UoIHRlY2hfTiA9IGxlbmd0aChUcnVlX0NvdW50KSwNCiAgICAgICAgICAgICB0ZWNoX21lYW4gPSBtZWFuKFRydWVfQ291bnQpLA0KICAgICAgICAgICAgIHRlY2hfc2QgPSBzZChUcnVlX0NvdW50KSwNCiAgICAgICAgICAgICB0ZWNoX3NlID0gdGVjaF9zZC9zcXJ0KHRlY2hfTikpDQpkYXRhMw0KYGBgDQoNCiMjU3VtbWFyaXplIHNhbXBsZXMgYnkgaW5qZWN0aW9uIChhdmVyYWdlIGJvdGggaW5qZWN0aW9ucykNCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0KDQpkYXRhNCA8LSBkYXRhMyAlPiUgDQogIGdyb3VwX2J5KHBhcnRpY2xlX3NpemUsU2FtcGxlX0lELERpbHV0aW9uX2ZhY3RvcikgJT4lIA0KICBzdW1tYXJpc2UoIGlual9OID0gbGVuZ3RoKHRlY2hfbWVhbiksDQogICAgICAgICAgICAgaW5qX21lYW4gPSBtZWFuKHRlY2hfbWVhbiksDQogICAgICAgICAgICAgaW5qX3NkID0gc2QodGVjaF9tZWFuKSwNCiAgICAgICAgICAgICBpbmpfc2UgPSBpbmpfc2Qvc3FydChpbmpfTikpDQpkYXRhNA0KDQojIEF2ZXJhZ2UgdGVjaG5pY2FsIHJlcGxpY2F0ZXMgYW5kIG1lcmdlIHdpdGgga2V5DQptZXJnZSA8LSBsZWZ0X2pvaW4oa2V5LGRhdGEzLCBieT0gIlNhbXBsZV9JRCIpDQoNCm1lcmdlDQoNCiMgQXZlcmFnZSBpbmplY3Rpb24gcmVwbGljYXRlcyBhbmQgbWVyZ2Ugd2l0aCBrZXkNCm1lcmdlMSA8LSBsZWZ0X2pvaW4oa2V5LGRhdGE0LCBieT0gIlNhbXBsZV9JRCIpDQoNCm1lcmdlMQ0KYGBgDQoNCg0KDQojUXVpY2sgdmlzdWFsaXphdGlvbnMNCg0KIyMjIEdyYXBoaW5nIGFsbCBzYW1wbGVzDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnNhbXBsZV9wbG90IDwtIG1lcmdlICU+JQ0KICBnZ3Bsb3QoYWVzKHg9cGFydGljbGVfc2l6ZSwgeT10ZWNoX21lYW4sY29sb3I9SW5qZWN0aW9uICkpKyAjcGxvdA0KICBnZW9tX3JpYmJvbihhZXMoeW1pbj10ZWNoX21lYW4tdGVjaF9zZSwNCiAgICAgICAgICAgICAgICAgIHltYXg9dGVjaF9tZWFuK3RlY2hfc2UpLA0KICAgICAgICAgICAgICAgICAgYWxwaGE9MC4yLGZpbGwgPSBhbHBoYSgnZ3JleTEyJywgMC4yKSkgKyAjZXJyb3IgYmFycw0KICBnZW9tX2xpbmUoc2l6ZT0yLjApICsgeGxpbSgwLDUwMCkrICNsaW5lIHNpemUsIHgtYXhpcyBzY2FsZQ0KICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kPWMoMCwwKSkrICNzZXQgYm90dG9tIG9mIGdyYXBoDQogIHhsYWIoIlBhcnRpY2xlIFNpemUiKSArICMgWCBheGlzIGxhYmVsDQogIHlsYWIoIlxuTWVhbiBQYXJ0aWNsZSBDb25jZW50cmF0aW9uL21sXG4iKSArICMgWSBheGlzIGxhYmVsDQogIGdndGl0bGUoIk5hbm9zaWdodCBIaXN0b2dyYW0gb2ZcblZpcmdpbiBNb3VzZSBQbGFzbWEiKSsgI3RpdGxlDQogIGxhYnMoY29sb3I9IkluamVjdGlvbiIpKyAjTGFiZWwgdGFibGUgdGl0bGUNCiAgZmFjZXRfZ3JpZChBbmltYWwgfiBDb25kaXRpb24pKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxNDApKw0KICBhbm5vdGF0ZSgidGV4dCIsIHg9IDIzNSwgeSA9IDFFOSwgbGFiZWw9ICIxNDBubSIpDQoNCnNhbXBsZV9wbG90DQpgYGANCg0KIyMjIFBhcnRpY2xlIGNvbmNlbnRyYXRpb24gdmFsdWVzIGZvciBlYWNoIG9mIHRoZSBzYW1wbGVzDQpgYGB7cn0NCm1lcmdlMiA8LSBtZXJnZTEgJT4lIA0KICBncm91cF9ieShBbmltYWwsQ29uZGl0aW9uKSAlPiUgDQogIHN1bW1hcmlzZShwYXJ0aWNsZV9jb25jPXN1bShpbmpfbWVhbikpDQptZXJnZTINCmBgYA0KDQoNCiMjIyBTdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgcGFydGljbGUgY29uY2VudHJhdGlvbiAoYXZlcmFnaW5nIG49NiBmb3IgZWFjaCB0aW1lIHBvaW50KQ0KYGBge3J9DQptZXJnZTMgPC0gbWVyZ2UyICU+JSANCiAgZ3JvdXBfYnkoQ29uZGl0aW9uKSAlPiUgDQogIHN1bW1hcmlzZShDb25kaXRpb25fTj1sZW5ndGgocGFydGljbGVfY29uYyksDQogICAgICAgICAgICBDb25kaXRpb25fbWVhbiA9IG1lYW4ocGFydGljbGVfY29uYyksDQogICAgICAgICAgICBDb25kaXRpb25fc2QgPSBzZChwYXJ0aWNsZV9jb25jKSwNCiAgICAgICAgICAgIENvbmRpdGlvbl9zZSA9IENvbmRpdGlvbl9zZC9zcXJ0KENvbmRpdGlvbl9OKSkNCm1lcmdlMw0KYGBgDQoNCiMjI0JveHBsb3QNCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0KcGxvdDEgPC0gbWVyZ2UyICU+JSANCiAgI2ZpbHRlcighQW5pbWFsPT0gJzEzNzEnfCFDb25kaXRpb24gPT0gJ2xvd094eWdlbicpICU+JSANCiAgZ3JvdXBfYnkoQ29uZGl0aW9uKSAlPiUgDQogIGdncGxvdChhZXMoeD0gQ29uZGl0aW9uLCB5ID0gcGFydGljbGVfY29uYywgY29sb3I9Q29uZGl0aW9uKSkgKw0KICBnZW9tX2JveHBsb3QoY29sb3VyPSJibGFjayIsZmlsbD1OQSkgKyANCiAgZ2VvbV9wb2ludChhZXModGV4dCA9IHBhc3RlKCJBbmltYWw6IiwgQW5pbWFsKSksDQogICAgICAgICAgICAgcG9zaXRpb249J2ppdHRlcicsc2l6ZT0zKSsNCiAgeGxhYigiXG5UcmVhdG1lbnRcbiIpICsgIyBYIGF4aXMgbGFiZWwNCiAgeWxhYigiXG5FeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbA0KICBnZ3RpdGxlKCJHRCAxNy41IFBsYWNlbnRhbCBFeG9zb21lIFxuRXhwbGFudCBDdWx0dXJlIChVbHRyYWNlbnRyaWd1dGlvbilcbiIpKyAjdGl0bGUNCiAgbGFicyhjb2xvcj0iQ29uZGl0aW9uIikgIyBMYWJlbCB0YWJsZSB0aXRsZQ0KDQogIA0KcGxvdDENCmBgYA0KIyNJbnRlcmFjdGl2ZSBQbG90DQpgYGB7cn0NCiMgZ2dwbG90bHkocGxvdDEpDQpgYGANCg0KDQojIFN0YXRpc3RpY3MNCg0KYGBge3J9DQpmaXQgPC0gdC50ZXN0KHBhcnRpY2xlX2NvbmMgfiBDb25kaXRpb24sZGF0YT1tZXJnZTIpDQoNCnRpZHkoZml0KQ0KYGBgDQoNCg==